sort :: [a] -> [a]
sort = undefined
-- type checking
:t sort
collect :: [(a,b)] -> [(a,[b])]
collect = undefined
-- type checking
:t collect
discollect :: [(a,[b])] -> [(a,b)]
discollect = undefined
-- type checking
:t discollect
converse :: [(a,b)] -> [(b,a)]
converse = undefined
-- type checking
:t converse
comp :: [(a,b)] -> [(b,c)] -> [(a,c)]
comp = undefined
-- type checking
:t comp
(f >< g) (a,b) = (f a , g b)
-- type checking
:t (><)
--- data types
data Jog
data Dat
data Atl
:i Jog
:i Dat
:i Atl
f :: [(Dat,[Jog])] -> [(Jog,[Atl])] -> [(Atl,[Dat])]
f = undefined
-- type checking
:t f
db1 :: [(Dat,[Jog])]
db1=undefined
-- type checking
:t db1
db2 :: [(Jog,[Atl])]
db2 = undefined
-- type checking
:t db2
-- type checking (step 0)
:t (db1,db2)
-- type checking (step 1)
:t (discollect >< discollect) $ (db1,db2)
-- type checking (step 2)
:t uncurry comp . (discollect >< discollect) $ (db1,db2)
-- type checking (step 3)
:t converse . uncurry comp . (discollect >< discollect) $ (db1,db2)
-- type checking (step 4)
:t collect . converse . uncurry comp . (discollect >< discollect) $ (db1,db2)
-- type checking (step 5)
:t map (id >< sort) . collect . converse . uncurry comp . (discollect >< discollect) $ (db1,db2)
-- type checking (step 6)
:t sort . map (id >< sort) . collect . converse . uncurry comp . (discollect >< discollect) $ (db1,db2)
f :: [(Dat,[Jog])] -> [(Jog,[Atl])] -> [(Atl,[Dat])]
f db1 db2 = sort . map (id >< sort) . collect . converse . uncurry comp . (discollect >< discollect) $ (db1,db2)
-- type checking
:t f